package com.lekang.system.controller;

import java.util.List;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.CacheControl;
import com.lekang.common.annotation.Log;
import com.lekang.common.core.controller.BaseController;
import com.lekang.common.core.domain.AjaxResult;
import com.lekang.common.enums.BusinessType;
import com.lekang.system.domain.TaskArrangement;
import com.lekang.system.service.ITaskArrangementService;
import com.lekang.common.utils.poi.ExcelUtil;
import com.lekang.common.core.page.TableDataInfo;
import java.util.ArrayList;

/**
 * 任务安排Controller
 *
 * @author zhihao
 * @since 2025-10-14
 */
@RestController
@RequestMapping("/system/arrangement")
public class TaskArrangementController extends BaseController
{
    @Autowired
    private ITaskArrangementService taskArrangementService;
    
    @Autowired
    private com.lekang.system.service.ITaskSchedulerService taskSchedulerService;
    
    @Autowired
    private com.lekang.system.mapper.CheckInManagementMapper checkInManagementMapper;
    
    @Autowired
    private com.lekang.system.mapper.CaregiverBedBindingMapper caregiverBedBindingMapper;
    
    @Autowired
    private com.lekang.system.mapper.NursingItemPlanBindingMapper nursingItemPlanBindingMapper;

    /**
     * 查询任务安排列表
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:list')")
    @GetMapping("/list")
    public TableDataInfo list(TaskArrangement taskArrangement)
    {
        startPage();
        List<TaskArrangement> list = taskArrangementService.selectTaskArrangementList(taskArrangement);
        return getDataTable(list);
    }

    /**
     * 多表联查任务安排列表
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:list')")
    @GetMapping("/joinList")
    public TableDataInfo joinList(@RequestParam Map<String, Object> params)
    {
        startPage();
        List<Map<String, Object>> list = taskArrangementService.selectTaskArrangementJoinList(params);
        return getDataTable(list);
    }

    /**
     * 导出任务安排列表
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:export')")
    @Log(title = "任务安排", businessType = BusinessType.EXPORT)
    @GetMapping("/export")  // 确保是GET请求
    public void export(HttpServletResponse response, TaskArrangement taskArrangement) {
        List<TaskArrangement> list = taskArrangementService.selectTaskArrangementList(taskArrangement);
        ExcelUtil<TaskArrangement> util = new ExcelUtil<>(TaskArrangement.class);
        util.exportExcel(response, list, "任务安排数据");
    }

    /**
     * 获取任务安排详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(taskArrangementService.selectTaskArrangementById(id));
    }

    /**
     * 新增任务安排
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:add')")
    @Log(title = "任务安排", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody TaskArrangement taskArrangement)
    {
        return toAjax(taskArrangementService.insertTaskArrangement(taskArrangement));
    }

    /**
     * 修改任务安排
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:edit')")
    @Log(title = "任务安排", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody TaskArrangement taskArrangement)
    {
        return toAjax(taskArrangementService.updateTaskArrangement(taskArrangement));
    }

    /**
     * 删除任务安排
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:remove')")
    @Log(title = "任务安排", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(taskArrangementService.deleteTaskArrangementByIds(ids));
    }

    /**
     * 获取任务安排详细信息（多表联查版本）
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:query')")
    @GetMapping(value = "/detail/{id}")
    public AjaxResult getDetail(@PathVariable("id") Long id) {
        return success(taskArrangementService.selectTaskArrangementDetail(id));
    }

    /**
     * 根据状态查询任务安排列表
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:list')")
    @GetMapping("/listByStatus")
    public TableDataInfo listByStatus(@RequestParam Map<String, Object> params) {
        startPage();
        List<Map<String, Object>> list = taskArrangementService.selectTaskArrangementByStatus(params);
        return getDataTable(list);
    }

    /**
     * PC端：今日待执行任务（护理员看自己，超管看全部），按服务时间升序
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:list')")
    @GetMapping("/pc/today-pending")
    public TableDataInfo pcTodayPending(@RequestParam Map<String, Object> params) {
        startPage();
        // Service层会根据用户角色自动添加executorId过滤
        List<Map<String, Object>> list = taskArrangementService.selectPcTodayPending(params);
        return getDataTable(list);
    }

    /**
     * 取消任务
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:edit')")
    @Log(title = "任务安排", businessType = BusinessType.UPDATE)
    @PostMapping("/cancel")
    public AjaxResult cancel(@RequestBody Map<String, Object> params) {
        return toAjax(taskArrangementService.cancelTask(params));
    }

    /**
     * 执行任务
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:edit')")
    @Log(title = "任务安排", businessType = BusinessType.UPDATE)
    @PostMapping("/execute")
    public AjaxResult execute(@RequestBody Map<String, Object> params) {
        return toAjax(taskArrangementService.executeTask(params));
    }

    /**
     * 改期任务
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:edit')")
    @Log(title = "任务安排", businessType = BusinessType.UPDATE)
    @PostMapping("/reschedule")
    public AjaxResult reschedule(@RequestBody Map<String, Object> params) {
        return toAjax(taskArrangementService.rescheduleTask(params));
    }

    /**
     * 查询护理项目列表（用于搜索）
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:list')")
    @GetMapping("/nursingProjects")
    public AjaxResult nursingProjects(@RequestParam Map<String, Object> params) {
        List<Map<String, Object>> list = taskArrangementService.selectNursingProjectsForSearch(params);
        return success(list);
    }

    /**
     * 生成护理计划内任务
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:add')")
    @Log(title = "任务安排", businessType = BusinessType.INSERT)
    @PostMapping("/generateNursingPlanTasks")
    public AjaxResult generateNursingPlanTasks(@RequestBody Map<String, Object> params) {
        return toAjax(taskArrangementService.generateNursingPlanTasks(params));
    }

    /**
     * 生成护理计划外任务
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:add')")
    @Log(title = "任务安排", businessType = BusinessType.INSERT)
    @PostMapping("/generateNonNursingPlanTasks")
    public AjaxResult generateNonNursingPlanTasks(@RequestBody Map<String, Object> params) {
        return toAjax(taskArrangementService.generateNonNursingPlanTasks(params));
    }

    /**
     * 根据执行周期生成任务
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:add')")
    @Log(title = "任务安排", businessType = BusinessType.INSERT)
    @PostMapping("/generateTasksByCycle")
    public AjaxResult generateTasksByCycle(@RequestBody Map<String, Object> params) {
        Long elderlyId = Long.valueOf(params.get("elderlyId").toString());
        Long nursingItemId = Long.valueOf(params.get("nursingItemId").toString());
        String executionCycleType = params.get("executionCycleType").toString();
        Integer executionFrequency = Integer.valueOf(params.get("executionFrequency").toString());
        String plannedStartTimeStr = params.get("plannedStartTime").toString();
        String projectType = params.get("projectType").toString();
        
        // 解析时间字符串
        java.util.Date plannedStartTime;
        try {
            plannedStartTime = new java.text.SimpleDateFormat("HH:mm:ss").parse(plannedStartTimeStr);
        } catch (Exception e) {
            return error("时间格式错误");
        }
        
        return toAjax(taskArrangementService.generateTasksByCycle(elderlyId, nursingItemId, 
            executionCycleType, executionFrequency, plannedStartTime, projectType));
    }

    /**
     * 手动触发任务生成（测试用）
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:add')")
    @Log(title = "任务安排", businessType = BusinessType.INSERT)
    @PostMapping("/testGenerateTasks")
    public AjaxResult testGenerateTasks(@RequestBody Map<String, Object> params) {
        try {
            // 测试生成每日任务
            // 添加参数验证
            if (params.get("elderlyId") == null || params.get("nursingItemId") == null || 
                params.get("executionFrequency") == null || params.get("plannedStartTime") == null) {
                return error("参数不能为空");
            }
            
            Long elderlyId = Long.valueOf(params.get("elderlyId").toString());
            Long nursingItemId = Long.valueOf(params.get("nursingItemId").toString());
            Integer executionFrequency = Integer.valueOf(params.get("executionFrequency").toString());
            String plannedStartTimeStr = params.get("plannedStartTime").toString();
            
            // 解析时间字符串
            java.util.Date plannedStartTime;
            try {
                plannedStartTime = new java.text.SimpleDateFormat("HH:mm:ss").parse(plannedStartTimeStr);
            } catch (Exception e) {
                return error("时间格式错误");
            }
            
            // 生成任务
            List<TaskArrangement> tasks = com.lekang.system.utils.TaskGenerationUtils.generateDailyTasks(
                elderlyId, nursingItemId, executionFrequency, plannedStartTime, "护理计划内");
            
            // 批量插入任务
            int result = 0;
            for (TaskArrangement task : tasks) {
                result += taskArrangementService.insertTaskArrangement(task);
            }
            
            return success("测试任务生成成功，共生成 " + result + " 个任务");
        } catch (Exception e) {
            return error("测试任务生成失败: " + e.getMessage());
        }
    }

    /**
     * 手动触发任务刷新（测试用）
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:list')")
    @PostMapping("/testRefreshTasks")
    public AjaxResult testRefreshTasks() {
        try {
            // 查询所有未执行的任务
            Map<String, Object> params = new java.util.HashMap<>();
            params.put("status", "待执行");
            
            List<Map<String, Object>> unfinishedTasks = taskArrangementService.selectTaskArrangementByStatus(params);
            
            return success("任务刷新测试完成，当前有 " + unfinishedTasks.size() + " 个待执行任务");
        } catch (Exception e) {
            return error("任务刷新测试失败: " + e.getMessage());
        }
    }

    /**
     * 图片上传接口
     */
    @PostMapping("/upload")
    public AjaxResult upload(@RequestParam("file") MultipartFile file) {
        try {
            if (file.isEmpty()) {
                return error("上传文件不能为空");
            }
            
            // 检查文件类型
            String contentType = file.getContentType();
            if (contentType == null || !contentType.startsWith("image/")) {
                return error("只能上传图片文件");
            }
            
            // 检查文件大小 (2MB)
            if (file.getSize() > 2 * 1024 * 1024) {
                return error("图片大小不能超过2MB");
            }
            
            // 生成文件名
            String originalFilename = file.getOriginalFilename();
            if (originalFilename == null || !originalFilename.contains(".")) {
                return error("文件名格式错误");
            }
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String fileName = System.currentTimeMillis() + extension;
            
            // 使用新的上传路径配置
            String uploadPath = "D:/Lekang/le-kang-service/uploads/";
            File uploadDir = new File(uploadPath);
            if (!uploadDir.exists()) {
                if (!uploadDir.mkdirs()) {
                    return error("创建上传目录失败: " + uploadPath);
                }
            }
            
            File destFile = new File(uploadDir, fileName);
            file.transferTo(destFile);
            
            // 验证文件是否保存成功
            if (!destFile.exists()) {
                return error("文件保存失败");
            }
            
            // 返回文件访问URL - 使用新的路径
            String fileUrl = "/uploads/" + fileName;
            
            // 添加调试信息
            System.out.println("文件上传成功:");
            System.out.println("上传路径: " + uploadPath);
            System.out.println("文件路径: " + destFile.getAbsolutePath());
            System.out.println("文件大小: " + destFile.length() + " bytes");
            System.out.println("访问URL: " + fileUrl);
            
            Map<String, Object> result = new java.util.HashMap<>();
            result.put("url", fileUrl);
            result.put("fileName", fileName);
            
            return success(result);
        } catch (Exception e) {
            return error("上传失败: " + e.getMessage());
        }
    }
    
    /**
     * 测试图片获取接口是否可用
     */
    @GetMapping("/test-image-endpoint")
    public AjaxResult testImageEndpoint() {
        return success("图片获取接口可用");
    }
    
    /**
     * 测试静态资源访问
     */
    @GetMapping("/test-static")
    public AjaxResult testStatic() {
        try {
            String projectPath = System.getProperty("user.dir");
            String uploadPath = projectPath + File.separator + "lekang-lkyl" + File.separator + "src" + File.separator + "main" + File.separator + "resources" + File.separator + "static" + File.separator + "uploads" + File.separator;
            
            File uploadDir = new File(uploadPath);
            boolean dirExists = uploadDir.exists();
            String[] files = dirExists ? uploadDir.list() : new String[0];
            
            Map<String, Object> result = new java.util.HashMap<>();
            result.put("projectPath", projectPath);
            result.put("uploadPath", uploadPath);
            result.put("dirExists", dirExists);
            result.put("files", files != null ? java.util.Arrays.asList(files) : java.util.Collections.emptyList());
            result.put("staticResourceUrl", "http://localhost:8080/static/uploads/");
            
            return success(result);
        } catch (Exception e) {
            return error("测试失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取上传的图片文件 - 直接返回图片文件流
     */
    @GetMapping("/image/{filename}")
    public ResponseEntity<byte[]> getImage(@PathVariable String filename) {
        try {
            String projectPath = System.getProperty("user.dir");
            String uploadPath = projectPath + File.separator + "lekang-lkyl" + File.separator + "src" + File.separator + "main" + File.separator + "resources" + File.separator + "static" + File.separator + "uploads" + File.separator;
            File imageFile = new File(uploadPath + filename);
            
            System.out.println("尝试获取图片文件:");
            System.out.println("项目路径: " + projectPath);
            System.out.println("上传路径: " + uploadPath);
            System.out.println("文件路径: " + imageFile.getAbsolutePath());
            System.out.println("文件存在: " + imageFile.exists());
            
            if (!imageFile.exists()) {
                System.out.println("图片文件不存在: " + filename);
                return ResponseEntity.notFound().build();
            }
            
            byte[] imageBytes = Files.readAllBytes(imageFile.toPath());
            
            // 根据文件扩展名确定MIME类型
            String mimeType = "application/octet-stream";
            if (filename.toLowerCase().endsWith(".png")) {
                mimeType = "image/png";
            } else if (filename.toLowerCase().endsWith(".jpg") || filename.toLowerCase().endsWith(".jpeg")) {
                mimeType = "image/jpeg";
            } else if (filename.toLowerCase().endsWith(".gif")) {
                mimeType = "image/gif";
            } else if (filename.toLowerCase().endsWith(".webp")) {
                mimeType = "image/webp";
            }
            
            System.out.println("成功读取图片文件，大小: " + imageBytes.length + " bytes, MIME类型: " + mimeType);
            
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType(mimeType));
            headers.setContentLength(imageBytes.length);
            headers.setCacheControl(CacheControl.maxAge(1, TimeUnit.HOURS).cachePublic());
            
            return ResponseEntity.ok()
                    .headers(headers)
                    .body(imageBytes);
                    
        } catch (Exception e) {
            System.out.println("获取图片失败: " + e.getMessage());
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    /**
     * 手动触发任务生成（用于测试）
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:list')")
    @PostMapping("/generate-test-tasks")
    public AjaxResult generateTestTasks() {
        try {
            taskSchedulerService.generateTestTasks();
            return success("测试任务生成完成，已生成6条测试数据");
        } catch (Exception e) {
            return error("生成测试任务失败: " + e.getMessage());
        }
    }
    
    /**
     * 手动触发今日任务生成（根据护理计划、床位分配的护理员）
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:list')")
    @PostMapping("/generate-today-tasks")
    public AjaxResult generateTodayTasks() {
        try {
            java.util.Map<String, Object> stats = taskSchedulerService.generateMonthlyTasks();
            return success(stats);
        } catch (Exception e) {
            return error("生成今日任务失败: " + e.getMessage());
        }
    }
    
    /**
     * 调试接口：检查任务生成所需的数据（无需权限）
     */
    @GetMapping("/debug-task-generation")
    public AjaxResult debugTaskGeneration() {
        try {
            java.util.Map<String, Object> debugInfo = new java.util.HashMap<>();
            
            // 查询在住老人及护理计划
            List<Map<String, Object>> elderlyList = checkInManagementMapper.selectElderlyWithNursingPlans();
            debugInfo.put("elderlyWithPlansCount", elderlyList.size());
            debugInfo.put("elderlyList", elderlyList);
            
            // 检查每个老人的床位和护理员分配
            java.util.List<Map<String, Object>> detailList = new java.util.ArrayList<>();
            for (Map<String, Object> elderly : elderlyList) {
                Map<String, Object> detail = new java.util.HashMap<>();
                detail.put("elderlyInfo", elderly);
                
                Long bedId = elderly.get("bed_id") != null ? Long.valueOf(elderly.get("bed_id").toString()) : null;
                if (bedId != null) {
                    List<Long> caregiverIds = caregiverBedBindingMapper.selectCaregiverIdsByBedId(bedId);
                    detail.put("caregiverIds", caregiverIds);
                    detail.put("caregiverCount", caregiverIds != null ? caregiverIds.size() : 0);
                    
                    Long nursingPlanId = elderly.get("nursing_plan_id") != null ? Long.valueOf(elderly.get("nursing_plan_id").toString()) : null;
                    if (nursingPlanId != null) {
                        List<com.lekang.system.domain.NursingItemPlanBinding> bindings = nursingItemPlanBindingMapper.selectByPlanId(nursingPlanId);
                        detail.put("nursingItemsCount", bindings.size());
                        detail.put("nursingItems", bindings);
                    }
                }
                
                detailList.add(detail);
            }
            
            debugInfo.put("detailList", detailList);
            
            return success(debugInfo);
        } catch (Exception e) {
            return error("调试失败: " + e.getMessage());
        }
    }

    /**
     * 手动触发每日任务刷新（用于测试）
     */
    @PreAuthorize("@ss.hasPermi('system:arrangement:list')")
    @PostMapping("/refresh-daily-tasks")
    public AjaxResult refreshDailyTasks() {
        try {
            taskArrangementService.refreshUnexecutedTasks();
            return success("每日任务刷新完成");
        } catch (Exception e) {
            return error("刷新任务失败: " + e.getMessage());
        }
    }

    /**
     * 调试接口：查看今日待执行任务的详细查询信息（无需认证）
     */
    @GetMapping("/debug-today-pending")
    public AjaxResult debugTodayPending() {
        try {
            java.util.Map<String, Object> debugInfo = new java.util.HashMap<>();
            
            // 查询今天所有待执行的任务（不加其他条件）
            java.util.Map<String, Object> params = new java.util.HashMap<>();
            params.put("status", "待执行");
            java.util.List<java.util.Map<String, Object>> allPendingTasks = 
                taskArrangementService.selectTaskArrangementJoinList(params);
            
            // 今天的日期
            String today = java.time.LocalDate.now().toString();
            
            // 筛选今天的任务
            java.util.List<java.util.Map<String, Object>> todayTasks = new java.util.ArrayList<>();
            for (java.util.Map<String, Object> task : allPendingTasks) {
                String expectedTime = task.get("expected_service_time").toString();
                if (expectedTime.startsWith(today)) {
                    todayTasks.add(task);
                }
            }
            
            debugInfo.put("today", today);
            debugInfo.put("totalPendingTasks", allPendingTasks.size());
            debugInfo.put("todayPendingTasks", todayTasks.size());
            debugInfo.put("todayTasksList", todayTasks);
            
            return success(debugInfo);
        } catch (Exception e) {
            return error("调试失败: " + e.getMessage());
        }
    }

    /**
     * 为 user07 生成今日测试任务（无需认证，用于测试）
     */
    @PostMapping("/create-test-data")
    public AjaxResult createTestData() {
        try {
            // 获取今天的日期
            java.time.LocalDate today = java.time.LocalDate.now();
            
            // 查询 user07 的 user_id
            Long user07Id = 7L; // user07 的 user_id
            
            // 查询数据库中实际存在的老人ID（从已有任务中获取）
            java.util.Map<String, Object> queryParams = new java.util.HashMap<>();
            queryParams.put("pageNum", 1);
            queryParams.put("pageSize", 10);
            java.util.List<java.util.Map<String, Object>> existingTasks = 
                taskArrangementService.selectTaskArrangementJoinList(queryParams);
            
            if (existingTasks == null || existingTasks.isEmpty()) {
                return error("数据库中没有现有任务数据，无法生成测试任务。请先在系统中添加老人和护理项目数据。");
            }
            
            // 使用已存在任务中的老人ID和护理项目ID，为 user07 创建今日任务
            int createdCount = 0;
            for (int i = 0; i < Math.min(3, existingTasks.size()); i++) {
                java.util.Map<String, Object> existingTask = existingTasks.get(i);
                
                TaskArrangement task = new TaskArrangement();
                // 使用实际存在的老人ID和护理项目ID
                task.setElderlyId(Long.valueOf(existingTask.get("elderly_id").toString()));
                task.setProjectNameId(Long.valueOf(existingTask.get("project_name_id").toString()));
                task.setProjectType("护理计划内");
                
                // 设置今天的不同时间点
                java.time.LocalDateTime taskTime = today.atTime(9 + i * 3, 0); // 9:00, 12:00, 15:00
                task.setExpectedServiceTime(java.sql.Timestamp.valueOf(taskTime));
                
                // 重点：设置执行人为 user07
                task.setExecutor(user07Id);
                
                task.setStatus("待执行");
                task.setCreateTime(new java.util.Date());
                task.setRelatedOrderNo("USER07-TEST-" + System.currentTimeMillis() + "-" + i);
                
                taskArrangementService.insertTaskArrangement(task);
                createdCount++;
            }
            
            return success("测试数据生成成功！已为 user07 创建 " + createdCount + " 条今天的待执行任务。请刷新页面并点击'今日待执行'按钮查看。");
        } catch (Exception e) {
            return error("生成测试数据失败: " + e.getMessage());
        }
    }
}